package wuziqi;

import javax.swing.*;

//电脑类 计算分值
public class Computer {
    private GamePanle gamePanle;
    public Computer(GamePanle gamePanle){
        this.gamePanle=gamePanle;
    }
    private int getTupleFiveScore(int 电脑棋子数, int 玩家棋子数) {
        // 1、该五元组中既有电脑的棋子又有玩家的棋子，大家一起完蛋，得0分。
        if (电脑棋子数 > 0 && 玩家棋子数 > 0) {
            return 0;
        }

        // 2、该五元组为空，没有棋子，得7分。
        if (电脑棋子数 == 0 && 玩家棋子数 == 0) {
            return 7;
        }

        // 3、该五元组中只有1个机器的棋子，其他为空，得35分。（电脑才下一个棋子，可以先看看。【优先级第七】）
        if (电脑棋子数 == 1) {
            return 35;
        }

        // 4、该五元组中只有2个机器的棋子，其他为空，得800分。（电脑下两个棋子了。【优先级第五】）
        if (电脑棋子数 == 2) {
            return 800;
        }

        // 5、该五元组中只有3个机器的棋子，其他为空，得15000分。（电脑看到赢的希望了，可以下这个点上，进攻。【优先级第三】）
        if (电脑棋子数 == 3) {
            return 15000;
        }

        // 6、该五元组中只有4个机器的棋子，其他为空，得800000分。（电脑马上就要赢了，无论如何也必须下这个点上，进攻。【优先级第一】）
        if (电脑棋子数 == 4) {
            return 800000;
        }

        // 7、该五元组中只有1个玩家的棋子，其他为空，得15分。（玩家才下一个棋子，别理他。【没优先级】）
        if (玩家棋子数 == 1) {
            return 15;
        }


        // 8、该五元组中只有2个玩家的棋子，其他为空，得400分。（玩家下两个棋子了。【优先级第六】）
        if (玩家棋子数 == 2) {
            return 400;
        }

        // 9、该五元组中只有3个玩家的棋子，其他为空，得1800分。（玩家看到赢的希望了，如果电脑没有类似的情况就得堵住这个点，防守。【优先级第四】）
        if (玩家棋子数 == 3) {
            return 1800;
        }


        // 10、该五元组中只有4个玩家的棋子，其他为空，得100000分。（玩家马上就要赢了，如果电脑要是不能立刻赢的话就必须下在这个点上，必须防守【优先级第二】）
        if (玩家棋子数 == 4) {
            return 100000;
        }

        return 0;
    }
    public Step getAiStep() {
        int 元组电脑棋子数; // 五元组中电脑棋子数目累计
        int 元组玩家棋子数; // 五元组中玩家棋子数目累计

        int tupleScore; // 五元组评分值

        int[][] scoreArray = new int[Const.横格数][Const.纵格数]; // 棋盘中每个落子交叉点的评分数组
        int[][] chessArray = new int[Const.横格数][Const.纵格数]; // 棋盘中每个落子交叉点的棋子数组

        // 初始化评分与棋子数组
        for (int i = 0; i < Const.横格数; i++) {
            for (int j = 0; j < Const.纵格数; j++) {
                scoreArray[i][j] = 0;
                chessArray[i][j] = 0;
            }
        }

        // 为棋子数组赋值，有利于计算且观察。
        for (int i = 0; i < this.gamePanle.全谱.size(); i++) {
            Step step = this.gamePanle.全谱.get(i);
            chessArray[step.x][step.y] = step.黑白标志;
        }

        // 开始循环
        for (int i = 0; i < Const.横格数; i++) {
            for (int j = 0; j < Const.纵格数; j++) {
                // 1、以该点为龙头向右寻找五元组
                if (i + 4 < Const.横格数) // 这个五元组真的有 //这里用横格数或纵格数都一样，就是19
                {
                    // 初始化变量
                    元组电脑棋子数 = 0;
                    元组玩家棋子数 = 0;
                    tupleScore = 0;
                    // 得到该五元组中电脑与玩家的棋子数目
                    for (int k = 0; k < 5; k++) {
                        if (chessArray[i + k][j] == this.gamePanle.电脑棋子颜色)
                            元组电脑棋子数++;
                        if (chessArray[i + k][j] == this.gamePanle.玩家棋子颜色)
                            元组玩家棋子数++;
                    }
                    // 得到该五元组的评分
                    tupleScore = this.getTupleFiveScore(元组电脑棋子数, 元组玩家棋子数);
                    // 将该评分赋值给五元组中的5个点
                    for (int k = 0; k < 5; k++) {
                        scoreArray[i + k][j] = scoreArray[i + k][j] + tupleScore;
                    }
                }

                // 2、以该点为龙头向下寻找五元组
                if (j + 4 < Const.横格数) // 这个五元组真的有
                {
                    // 初始化变量
                    元组电脑棋子数 = 0;
                    元组玩家棋子数 = 0;
                    tupleScore = 0;
                    // 得到该五元组中电脑与玩家的棋子数目
                    for (int k = 0; k < 5; k++) {
                        if (chessArray[i][j + k] == this.gamePanle.电脑棋子颜色) {
                            元组电脑棋子数++;
                        }
                        if (chessArray[i][j + k] == this.gamePanle.玩家棋子颜色) {
                            元组玩家棋子数++;
                        }
                    }
                    // 得到该五元组的评分
                    tupleScore = this.getTupleFiveScore(元组电脑棋子数, 元组玩家棋子数);
                    // 将该评分赋值给五元组中的5个点
                    for (int k = 0; k < 5; k++) {
                        scoreArray[i][j + k] = scoreArray[i][j + k] + tupleScore;
                    }
                }

                // 3、以该点为龙头135度斜下寻找五元组
                if (i + 4 < Const.横格数 && j + 4 <= 14) // 这个五元组真的有
                {
                    // 初始化变量
                    元组电脑棋子数 = 0;
                    元组玩家棋子数 = 0;
                    tupleScore = 0;
                    // 得到该五元组中电脑与玩家的棋子数目
                    for (int k = 0; k < 5; k++) {
                        if (chessArray[i + k][j + k] == this.gamePanle.电脑棋子颜色) {
                            元组电脑棋子数++;
                        }
                        if (chessArray[i + k][j + k] == this.gamePanle.玩家棋子颜色) {
                            元组玩家棋子数++;
                        }
                    }
                    // 得到该五元组的评分
                    tupleScore = this.getTupleFiveScore(元组电脑棋子数, 元组玩家棋子数);
                    // 将该评分赋值给五元组中的5个点
                    for (int k = 0; k < 5; k++) {
                        scoreArray[i + k][j + k] = scoreArray[i + k][j + k] + tupleScore;
                    }
                }

                // 3、以该点为龙头135度斜下寻找五元组
                if (i + 4 < Const.横格数 && j + 4 <= 14) // 这个五元组真的有
                {
                    // 初始化变量
                    元组电脑棋子数 = 0;
                    元组玩家棋子数 = 0;
                    tupleScore = 0;
                    // 得到该五元组中电脑与玩家的棋子数目
                    for (int k = 0; k < 5; k++) {
                        if (chessArray[i + k][j + k] == this.gamePanle.电脑棋子颜色) {
                            元组电脑棋子数++;
                        }
                        if (chessArray[i + k][j + k] == this.gamePanle.玩家棋子颜色) {
                            元组玩家棋子数++;
                        }
                    }
                    // 得到该五元组的评分
                    tupleScore = this.getTupleFiveScore(元组电脑棋子数, 元组玩家棋子数);
                    // 将该评分赋值给五元组中的5个点
                    for (int k = 0; k < 5; k++) {
                        scoreArray[i + k][j + k] = scoreArray[i + k][j + k] + tupleScore;
                    }
                }

                // 4、以该点为龙头45度斜下寻找五元组
                if (i - 4 >= 0 && j + 4 < Const.横格数) // 这个五元组真的有
                {
                    // 初始化变量
                    元组电脑棋子数 = 0;
                    元组玩家棋子数 = 0;
                    tupleScore = 0;
                    // 得到该五元组中电脑与玩家的棋子数目
                    for (int k = 0; k < 5; k++) {
                        if (chessArray[i - k][j + k] == this.gamePanle.电脑棋子颜色) {
                            元组电脑棋子数++;
                        }
                        if (chessArray[i - k][j + k] == this.gamePanle.玩家棋子颜色) {
                            元组玩家棋子数++;
                        }
                    }
                    // 得到该五元组的评分
                    tupleScore = this.getTupleFiveScore(元组电脑棋子数, 元组玩家棋子数);
                    // 将该评分赋值给五元组中的5个点
                    for (int k = 0; k < 5; k++) {
                        scoreArray[i - k][j + k] = scoreArray[i - k][j + k] + tupleScore;
                    }
                }
            }
        }

        // 从空位置中找到得分最大的位置
        int maxScore = 0;
        int maxX = -1;
        int maxY = -1;

        for (int i = 0; i < Const.横格数; i++) {
            for (int j = 0; j < Const.纵格数; j++) {
                //chessArray里面标注的是每个节点上的棋子是黑的还是白的,	初始的时的是 step.黑白标志(1 黑棋， 2 白棋)
                if (chessArray[i][j] == 0) { //证明这个位置上没有棋子
                    if (maxScore < scoreArray[i][j]) {
                        maxScore = scoreArray[i][j];
                        maxX = i;
                        maxY = j;
                    }
                }
            }
        }

        Step aiStep=new Step(maxX,maxY,this.gamePanle.电脑棋子颜色);
        return aiStep;
    }
    public void play() {
        Step aiStep = getAiStep();
        // 棋盘下满了，电脑无棋可下了
        if (aiStep.x == -1 || aiStep.y == -1) {
            JOptionPane.showMessageDialog(null, "人和电脑双方战平");
            this.gamePanle.isGameOver = true;
            this.gamePanle.initGame();
            return;
        }
        if (this.gamePanle.电脑棋子颜色 == Const.白棋标识_2) {
            this.gamePanle.白谱.add(aiStep);
        } else {
            this.gamePanle.黑谱.add(aiStep);
        }
        this.gamePanle.全谱.add(aiStep);

        gamePanle.repaint();
    }

}

